import sys
from PyQt6.QtWidgets import QApplication, QWidget
from TwoWinSignal import Ui_Form
#1.创建UI界面（定义成员变量）
class QmyCaculate(QWidget):
    def __init__(self, parent = None):#该窗口是顶级窗口，没有父窗口独立存在，若写为parent=parent_window，则此时为子窗口，会随着父窗口parent_window关闭而关闭
        super().__init__(parent)#调用父类并构造函数，创建Qwidget窗口，这里加上parent为默认写法，这里parent并不是继承中的传参，而是决定该新建窗口是显示在paernt窗口的
        self.label_text = ''  # 初始化标签文本
        self.edit_text = ''  # 初始化输入框文本
        self.num1 = ''  # 初始化第一个运算数
        self.num2 = ''  # 初始化第二个运算数
        self.dop = ''  # 初始化运算符（如 +、-、*、/）
        self.result = ''  # 初始化计算结果
        self._ui = Ui_Form()#创建UI对象
        self._ui.setupUi(self)#利用对象名打点调用Ui_Form()类中setupUi(self)的实例方法,这里必须要有self因为实例方法setupUi(self,Form)是两个参数，所以需要传入
        #这里调用的setupUi(self, Form)这个实例方法中第一个self传入的是self._ui这个实例对象，自动传入。第二个Form传入的是上面QmyCaculate中的self等于self._ui.setupUi(self)括号中的这个self
        self._ui.lineEdit.setText("0")
        self.bind()


#3.UI界面中控件功能实现（编辑成员方法）——注意这里还在类QmyCaculate(QWidget):中，所以还属于实例方法（由于计算器功能比较简单，所以放同一个类中）
        #3.1)数字按钮（0-9、00、小数点）功能,输入数字或小数点，构建运算数
    def on_number_clicked(self, num):
        if self.edit_text == '0' and num != '.':
            self.edit_text = num  # 如果当前是"0"，直接替换（避免"0123"）
        else:
            if num == '.' and '.' in self.edit_text:
                return  # 防止重复输入小数点（如"12..34"），这里相当于终止，不进行后面操作
            else:
                self.edit_text += num  # 追加数字
        self._ui.lineEdit.setText(self.edit_text)  # 更新显示

        # 3.2)运算符按钮（+、-、×、%）功能：选择运算类型（加减乘除）

    def on_operator_clicked(self, op):
        if self.edit_text:  # 检查是否有输入数字（这里调用了上一个实例方法中的实例变量，可以在同一个类的任何实例方法中直接使用。这是 Python 面向对象编程的基本特性之一，所有实例方法通过 self 访问的是同一份数据）
            if self.num1 and self.dop and not self.num2:  # 未输入第二个数时
                self.dop = op  # 替换未生效的运算符（如把"+"改成"-"）
                self._ui.label.setText(f"{self.num1} {self.dop}")
                return
            if not self.num1:
                self.num1 = self.edit_text  # 保存第一个数
                self.dop = op  # 保存运算符
                self._ui.label.setText(f"{self.num1} {self.dop}")
                self.edit_text = ''  # 清空输入框，准备输入第二个数
                self._ui.lineEdit.setText('0')
            elif self.num1 and not self.num2:  # 如果已经有第一个数，但没有第二个数，执行计算
                self.on_equal_clicked()
                self.num1 = self.result
                self.dop = op
                self.label_text = f"{self.num1} {self.dop}"
                self._ui.label.setText(self.label_text)
                self.edit_text = ''
                self._ui.lineEdit.setText('0')

        # 3.3)执行运算功能

    def on_equal_clicked(self):
        if self.num1 and self.dop and not self.num2 and self.edit_text:
            self.num2 = self.edit_text
            self.label_text = f"{self.num1} {self.dop} {self.num2} ="
            self._ui.label.setText(self.label_text)

            try:  # try...except 是 Python 中的 异常处理语法，用于捕获和处理代码运行时可能出现的错误（异常），防止程序崩溃。
                if self.dop == '+':
                    self.result = str(float(self.num1) + float(self.num2))
                elif self.dop == '-':
                    self.result = str(float(self.num1) - float(self.num2))
                elif self.dop == '×':
                    self.result = str(float(self.num1) * float(self.num2))
                elif self.dop == '%':
                    if float(self.num2) == 0:
                        self.result = "Error"
                    else:
                        self.result = str(float(self.num1) / float(self.num2))

                self.label_text = f"{self.num1} {self.dop} {self.num2} ={self.result}"
                self._ui.label.setText(self.label_text)
                self.edit_text = self.result
                self.num1 = ''
                self.num2 = ''
                self.dop = ''
            except:
                self._ui.lineEdit.setText("Error")
                self.reset_calculator()

        # 3.4) "清除"（Clear）按钮 的点击事件处理方法，作用是 将输入框内容重置为初始状态 "0"
    def on_clear_clicked(self):
        self.edit_text = '0'
        self._ui.lineEdit.setText(self.edit_text)

        # 3.5)完全重置计算器（AC）
    def on_clear_all_clicked(self):
        self.reset_calculator()
        self._ui.lineEdit.setText('0')
        self._ui.label.setText('')

        # 3.6)文本编辑中的退格按钮，如果文本长度大于1，则删除最后一个字符（使用切片操作[:-1]获取除最后一个字符外的所有字符）
    def on_backspace_clicked(self):
        if len(self.edit_text) > 1:
            self.edit_text = self.edit_text[:-1]#切片操作sequence[start:stop:step]，正向从0开始，负向从-1开始，左闭右开
        else:
            self.edit_text = '0'
        self._ui.lineEdit.setText(self.edit_text)

        # 3.7)恢复计算器初始状态被3.5调用
    def reset_calculator(self):
        self.label_text = ''
        self.edit_text = '0'
        self.num1 = ''
        self.num2 = ''
        self.dop = ''
        self.result = ''

        # 2.GUI 程序中的信号槽连接，用于将按钮的点击事件（clicked 信号）绑定到对应的处理函数（槽函数）
        # 2.1）连接数字按钮信号——需要额外参数num，所以需要lambda：（lambda 参数：表达式）由于这里是点击按钮无信号，但是又需要回调参数，所以是lambda：表达式
    def bind(self):
        self._ui.pushButton_0.clicked.connect(lambda: self.on_number_clicked('0'))
        self._ui.pushButton_00.clicked.connect(lambda: self.on_number_clicked('00'))
        self._ui.pushButton_01.clicked.connect(lambda: self.on_number_clicked('1'))
        self._ui.pushButton_02.clicked.connect(lambda: self.on_number_clicked('2'))
        self._ui.pushButton_03.clicked.connect(lambda: self.on_number_clicked('3'))
        self._ui.pushButton_04.clicked.connect(lambda: self.on_number_clicked('4'))
        self._ui.pushButton_05.clicked.connect(lambda: self.on_number_clicked('5'))
        self._ui.pushButton_06.clicked.connect(lambda: self.on_number_clicked('6'))
        self._ui.pushButton_07.clicked.connect(lambda: self.on_number_clicked('7'))
        self._ui.pushButton_08.clicked.connect(lambda: self.on_number_clicked('8'))
        self._ui.pushButton_09.clicked.connect(lambda: self.on_number_clicked('9'))
        self._ui.pushButton_dot.clicked.connect(lambda: self.on_number_clicked('.'))

        # 2.2）连接操作符按钮信号——需要额外参数op，所以需要lambda
        self._ui.pushButton_Add.clicked.connect(lambda: self.on_operator_clicked('+'))
        self._ui.pushButton_S.clicked.connect(lambda: self.on_operator_clicked('-'))
        self._ui.pushButton_M.clicked.connect(lambda: self.on_operator_clicked('×'))
        self._ui.pushButton_P.clicked.connect(lambda: self.on_operator_clicked('%'))

        # 2.3）连接功能按钮信号——这里不需要额外参数，直接连接即可，所以不需要lambda
        self._ui.pushButton_E.clicked.connect(self.on_equal_clicked)
        self._ui.C.clicked.connect(self.on_clear_clicked)
        self._ui.CE.clicked.connect(self.on_clear_all_clicked)
        self._ui.space.clicked.connect(self.on_backspace_clicked)

#4.显示该UI
if __name__ == "__main__":#惯用写法确保在直接运行时被执行
    app = QApplication(sys.argv)#创建一个实例应用
    myWindow = QmyCaculate()#创建一个UI对象
    myWindow.show()#显示该UI
    sys.exit(app.exec())#循环事件

#5打包发布